package com.gzhryc.shared_device.oem.h5.mng.controllers.bxscn;

import com.gzhryc.common.ClassTools;
import com.gzhryc.common.NumberTools;
import com.gzhryc.common.StringTools;
import com.gzhryc.common.data.dto.AjaxResult;
import com.gzhryc.common.data.dto.ListResult;
import com.gzhryc.common.exceptions.LogicException;
import com.gzhryc.common.json.JsonTools;
import com.gzhryc.common.kafka.JFKafkaProducer;
import com.gzhryc.common.kafka.KafkaProducerFactory;
import com.gzhryc.common.kafka.models.KafkaMessage;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.jdbc.DateBranchHelper;
import com.gzhryc.servlet.DtoConstants;
import com.gzhryc.servlet.WebUtils;
import com.gzhryc.servlet.annotation.Route;
import com.gzhryc.shared_device.base.enums.EOperatorType;
import com.gzhryc.shared_device.base.enums.EPayType;
import com.gzhryc.shared_device.base.models.OperateInfo;
import com.gzhryc.shared_device.base.models.OrderLogContent;
import com.gzhryc.shared_device.bxscn.code.dao.db.*;
import com.gzhryc.shared_device.bxscn.code.dao.enums.*;
import com.gzhryc.shared_device.bxscn.code.services.*;
import com.gzhryc.shared_device.bxscn.code.services.dto.BXSCNShopOrderSearch;
import com.gzhryc.shared_device.common.payment.dao.db.AlipayOrder;
import com.gzhryc.shared_device.common.payment.dao.db.WXPayOrder;
import com.gzhryc.shared_device.common.payment.dao.db.WXRefundOrder;
import com.gzhryc.shared_device.common.payment.services.AlipayOrderService;
import com.gzhryc.shared_device.common.payment.services.WXPayOrderService;
import com.gzhryc.shared_device.common.payment.services.WXRefundOrderService;
import com.gzhryc.shared_device.oem.code.KafkaEventConstants;
import com.gzhryc.shared_device.oem.code.PayServiceFactory;
import com.gzhryc.shared_device.oem.code.business.BXSCNShopBusinessEventListener;
import com.gzhryc.shared_device.oem.code.business.EBusinessType;
import com.gzhryc.shared_device.oem.code.member.services.MemberBusinessOrderService;
import com.gzhryc.shared_device.oem.code.member.services.MemberCouponService;
import com.gzhryc.shared_device.oem.code.order.RedisCacheManager;
import com.gzhryc.shared_device.oem.code.order.event.OrderFinishEvent;
import com.gzhryc.shared_device.oem.code.place.dao.db.PlacePhysicalStore;
import com.gzhryc.shared_device.oem.code.place.services.PlacePhysicalStoreService;
import com.gzhryc.shared_device.oem.code.profit.dao.db.BusinessOrder;
import com.gzhryc.shared_device.oem.code.profit.dao.enums.BusinessOrderEnum;
import com.gzhryc.shared_device.oem.code.profit.service.BusinessOrderService;
import com.gzhryc.shared_device.oem.h5.mng.WebConstants;
import com.gzhryc.system.SysConstants;
import com.gzhryc.system.dao.db.Manager;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.text.ParseException;
import java.util.Date;
import java.util.List;

public class BXSCNShopOrderController {

    static Logger log = Logger.getLogger(BXSCNShopOrderController.class);

    @Route("/bxscn/shop_order/list.html")
    public String list(HttpServletRequest request) {
        request.setAttribute("payStateList", BXSCNOrderEnum.PayState.values());
        request.setAttribute("stateList", BXSCNShopOrderEnum.State.values());
        request.setAttribute("dateBranchItemList", DateBranchHelper.self().getYearDateBranchItems());
        return "/bxscn/shop_order/list.html";
    }

    @Route(value = "/bxscn/shop_order/list.data")
    public ListResult<BXSCNShopOrder> listData(HttpServletRequest request) {
        ListResult<BXSCNShopOrder> result = new ListResult<>(DtoConstants.NULL_DATA, "暂无数据");
        BXSCNShopOrderSearch search = WebUtils.getParameter(request, BXSCNShopOrderSearch.class);
        String searchDate = WebUtils.getString(request,"searchDate");
        Integer pageNo = WebUtils.getInteger(request, "page", 1);
        Integer pageLimit = WebUtils.getInteger(request, "limit", WebConstants.PAGE_LIMIT);
        try {
            if (StringTools.isNotBlank(searchDate)) {
                String[] strings = searchDate.split(" - ");
                if (strings.length == 2) {
                    Date startDate = DateUtils.parseDate(strings[0], "yyyy-MM-dd");
                    Date endDate = DateUtils.parseDate(strings[1], "yyyy-MM-dd");
                    search.setStartDate(startDate);
                    search.setEndDate(endDate);
                }
            }
            Date dateBranch = new Date();
            if(StringTools.isNotBlank(search.getDateBranchId())){
                dateBranch = DateBranchHelper.getDateByItemId(search.getDateBranchId());
            }

            result.getBody().setTotal(BXSCNShopOrderService.self(dateBranch).countBySearch(search));
            List<BXSCNShopOrder> data = BXSCNShopOrderService.self(dateBranch).findBySearch(search, pageNo, pageLimit);
            if (data != null && data.size() > 0) {
                result.setCode(DtoConstants.SUCCESS, null);
                result.getBody().setData(data);
            }
        }catch (Exception e){
            result.setMsg(e.getMessage());
        }
        return result;
    }

    @Route("/bxscn/shop_order/info.html")
    public String info(HttpServletRequest request) {
        String tradeNo = WebUtils.getString(request,"tradeNo");
        Date createDate = WebUtils.getDate(request,"createDate");
        if(createDate == null){
            createDate = new Date();
        }
        BXSCNShopOrder deviceOrder = BXSCNShopOrderService.self(createDate).getByTradeNo(tradeNo);
        if(deviceOrder != null) {
            WebUtils.setAttribute(request, deviceOrder);
            if(EPayType.WXPay.index().equals(deviceOrder.getPayType())){
                WXPayOrder payOrder = WXPayOrderService.self(deviceOrder.getCreateDate()).getByTradeNo(deviceOrder.getPayTradeNo());
                if(payOrder != null) {
                    request.setAttribute("payOrder", payOrder);
                    List<WXRefundOrder> refundOrderList = WXRefundOrderService.self(deviceOrder.getCreateDate()).findByBusinessTradeNo(payOrder.getBusinessTradeNo());
                    request.setAttribute("refundOrderList", refundOrderList);
                }
            }else if(EPayType.Alipay.index().equals(deviceOrder.getPayType())) {
            	AlipayOrder payOrder = AlipayOrderService.self(deviceOrder.getCreateDate()).getByTradeNo(deviceOrder.getPayTradeNo());
            	if(payOrder != null) {
            		request.setAttribute("payOrder", payOrder);
            	}
            }
        }
        request.setAttribute("businessType", EBusinessType.BXSCN_SHOP);
        return "/bxscn/shop_order/info.html";
    }

    @Route(value = "/bxscn/shop_order/operate/record/list.data")
    public ListResult<OrderLogContent.LogItem> logListData(HttpServletRequest request) {
        ListResult<OrderLogContent.LogItem> result = new ListResult<>(DtoConstants.NULL_DATA, "暂无数据");
        String tradeNo = WebUtils.getString(request,"tradeNo");
        Date createDate = WebUtils.getDate(request,"createDate");
        if(createDate == null){
            createDate = new Date();
        }
        BXSCNShopOrderLog orderLog = BXSCNShopOrderLogService.self(createDate).getByTradeNo(tradeNo);
        if(orderLog != null && StringTools.isNotBlank(orderLog.getContent())){
            OrderLogContent logContent = JsonTools.fromJson(orderLog.getContent(),OrderLogContent.class);
            if(logContent != null){
                result.setCode(DtoConstants.SUCCESS,null);
                result.getBody().setData(logContent.getItems());
            }
        }
        return result;
    }

    @Route("/bxscn/shop_order/operate/lease.html")
    public String lease(HttpServletRequest request) {
        String tradeNo = WebUtils.getString(request,"tradeNo");
        Date createDate = WebUtils.getDate(request,"createDate");
        if(createDate == null){
            createDate = new Date();
        }
        BXSCNShopOrder deviceOrder = BXSCNShopOrderService.self(createDate).getByTradeNo(tradeNo);
        if(deviceOrder != null) {
            WebUtils.setAttribute(request, deviceOrder);
        }
        return "/bxscn/shop_order/lease.html";
    }

    @Route(value = {"/bxscn/shop_order/operate/lease.do"})
    public AjaxResult doLease(HttpServletRequest request, HttpSession session) {
        AjaxResult result = new AjaxResult(DtoConstants.EXECUTE_ERROR, "租借完成失败");
        String tradeNo = WebUtils.getString(request,"tradeNo");
        Date createDate = WebUtils.getDate(request,"createDate");
        if(createDate == null){
            createDate = new Date();
        }
        String portableBatterySn = WebUtils.getString(request,"portableBatterySn");
        if(StringTools.isBlank(portableBatterySn)){
            result.setMsg("请填写电池序列号");
            return result;
        }
        BXSCNShopOrder deviceOrder = BXSCNShopOrderService.self(createDate).getByTradeNo(tradeNo);
        if(deviceOrder != null) {
            if(!BXSCNShopOrderEnum.State.WaitLease.index().equals(deviceOrder.getState())){
                result.setMsg("订单状态异常");
                return result;
            }

            deviceOrder.setPortableBatterySn(portableBatterySn);

            Manager manager = WebUtils.getAttribute(session, SysConstants.SESSION_LOGIN_MANAGER, Manager.class);
            OperateInfo operateInfo = new OperateInfo(WebConstants.PROGRAM_TYPE,WebConstants.PROGRAM_TYPE_NAME);
            operateInfo.setOperator( EOperatorType.Manager.index(),manager.getFullName());

            BXSCNShopBusinessEventListener businessEventListener = new BXSCNShopBusinessEventListener();
            try {
                if (BXSCNShopOrderService.self(createDate).leaseFinish(deviceOrder, operateInfo,businessEventListener)) {
                    result.setCode(DtoConstants.SUCCESS, null);
                }
            } catch (LogicException e) {
                result.setMsg(e.getMessage());
            }
        }
        return result;
    }

    @Route("/bxscn/shop_order/operate/revert.html")
    public String revert(HttpServletRequest request) {
        String tradeNo = WebUtils.getString(request,"tradeNo");
        Date createDate = WebUtils.getDate(request,"createDate");
        if(createDate == null){
            createDate = new Date();
        }
        BXSCNShopOrder deviceOrder = BXSCNShopOrderService.self(createDate).getByTradeNo(tradeNo);
        if(deviceOrder != null) {
            WebUtils.setAttribute(request, deviceOrder);
        }
        request.setAttribute("revertTypeList",BXSCNShopOrderEnum.RevertType.values());
        return "/bxscn/shop_order/revert.html";
    }

    @Route(value = {"/bxscn/shop_order/operate/revert.do"})
    public AjaxResult doRevert(HttpServletRequest request, HttpSession session) {
        AjaxResult result = new AjaxResult(DtoConstants.EXECUTE_ERROR, "归还完成失败");
        String tradeNo = WebUtils.getString(request,"tradeNo");
        Long revertPlaceId = WebUtils.getLong(request,"revertPlaceId");
        Integer revertType = WebUtils.getInteger(request,"revertType");
        Date createDate = WebUtils.getDate(request,"createDate");
        if(createDate == null){
            createDate = new Date();
        }
        BXSCNShopOrder deviceOrder = BXSCNShopOrderService.self(createDate).getByTradeNo(tradeNo);
        if(deviceOrder != null) {
            if(!BXSCNShopOrderEnum.State.Lease.index().equals(deviceOrder.getState())){
                result.setMsg("订单状态异常");
                return result;
            }

            if(revertType != null && BXSCNShopOrderEnum.RevertType.Logistics.index().equals(revertType)){
                deviceOrder.setRevertType(revertType);
            }else{
                deviceOrder.setRevertType(BXSCNShopOrderEnum.RevertType.Appointment.index());
            }

            if(deviceOrder.getRevertPlaceId() == null || !deviceOrder.getRevertPlaceId().equals(revertPlaceId)){
                PlacePhysicalStore physicalStore = PlacePhysicalStoreService.self().getById(revertPlaceId);
                if(physicalStore == null){
                    result.setMsg("未找到归还的网点");
                    return result;
                }

                deviceOrder.setRevertPlaceId(physicalStore.getId());
                deviceOrder.setRevertPlaceName(physicalStore.getName());
                deviceOrder.setRevertProvince(physicalStore.getProvince());
                deviceOrder.setRevertCity(physicalStore.getCity());
                deviceOrder.setRevertCityArea(physicalStore.getCityArea());
                deviceOrder.setRevertAreaCode(physicalStore.getAreaCode());
                deviceOrder.setRevertAddress(physicalStore.getAddress());
                deviceOrder.setRevertAgentId(physicalStore.getUserId());
                deviceOrder.setRevertLatitude(physicalStore.getLatitude());
                deviceOrder.setRevertLongitude(physicalStore.getLongitude());
            }

            Manager manager = WebUtils.getAttribute(session, SysConstants.SESSION_LOGIN_MANAGER, Manager.class);
            OperateInfo operateInfo = new OperateInfo(WebConstants.PROGRAM_TYPE,WebConstants.PROGRAM_TYPE_NAME);
            operateInfo.setOperator( EOperatorType.Manager.index(),manager.getFullName());

            try {
                int finishResult = BXSCNShopOrderService.self(deviceOrder.getCreateDate()).revertFinish(deviceOrder, PayServiceFactory.self()
                        , MemberCouponService.self(), operateInfo);
                if(finishResult > 0) {
                    if(finishResult == 2) {
                        deviceOrder = BXSCNShopOrderService.self(new Date()).getByTradeNo(tradeNo);
                        //同步会员订单
                        if (!MemberBusinessOrderService.self(deviceOrder.getCreateDate()).finish(deviceOrder.getTradeNo(), deviceOrder.getMoney(), deviceOrder.getPayMoney()
                                , deviceOrder.getWalletMoney(),operateInfo)) {
                            log.error("修改会员订单失败，订单号：{{0}}", deviceOrder.getTradeNo());
                        }
                        //触发订单完成
                        JFKafkaProducer producer = KafkaProducerFactory.self().getProducer();
                        if (producer != null) {
                            OperateInfo temp = ClassTools.copy(new OperateInfo(), operateInfo);
                            OrderFinishEvent event = new OrderFinishEvent(EBusinessType.BXSCN_SHOP.index(), deviceOrder.getTradeNo(), deviceOrder.getCreateDate(), temp);
                            KafkaMessage kafkaMessage = new KafkaMessage(KafkaEventConstants.TOPIC_Order, KafkaEventConstants.KEY_OrderFinish, JsonTools.toJson(event));
                            producer.send(kafkaMessage);
                        } else {
                            log.error("未初始化消息队列，订单{{0}}未触发完成事件", deviceOrder.getTradeNo());
                        }
                    }
                    result.setCode(DtoConstants.SUCCESS, null);
                }
            } catch (LogicException e) {
                result.setMsg(e.getMessage());
            }
        }else{
            result.setMsg("未找到订单信息");
        }
        return result;
    }

    @Route("/bxscn/shop_order/operate/extension_lease_day.html")
    public String extensionLeaseDay(HttpServletRequest request) {
        String tradeNo = WebUtils.getString(request,"tradeNo");
        Date createDate = WebUtils.getDate(request,"createDate");
        if(createDate == null){
            createDate = new Date();
        }
        BXSCNShopOrder deviceOrder = BXSCNShopOrderService.self(createDate).getByTradeNo(tradeNo);
        if(deviceOrder != null) {
            WebUtils.setAttribute(request, deviceOrder);
        }
        return "/bxscn/shop_order/extension_lease_day.html";
    }

    @Route(value = {"/bxscn/shop_order/operate/extension_lease_day.do"})
    public AjaxResult doExtensionLeaseDay(HttpServletRequest request, HttpSession session) {
        AjaxResult result = new AjaxResult(DtoConstants.EXECUTE_ERROR, "租借延期失败");
        String tradeNo = WebUtils.getString(request,"tradeNo");
        String note = WebUtils.getString(request, "note");
        if (StringTools.isNotBlank(tradeNo)) {
            if (StringTools.isBlank(note)) {
                result.setMsg("请填撤销的原因");
                return result;
            }

            Date createDate = WebUtils.getDate(request,"createDate");
            if(createDate == null){
                createDate = new Date();
            }

            try {
                String extensionDate = WebUtils.getString(request, "extensionDate");
                Date startDate = DateUtils.parseDate(extensionDate, "yyyy-MM-dd");

                BXSCNShopOrder deviceOrder = BXSCNShopOrderService.self(createDate).getByTradeNo(tradeNo);
                if(deviceOrder != null) {
                    Manager manager = WebUtils.getAttribute(session, SysConstants.SESSION_LOGIN_MANAGER, Manager.class);
                    OperateInfo operateInfo = new OperateInfo(WebConstants.PROGRAM_TYPE,WebConstants.PROGRAM_TYPE_NAME);
                    operateInfo.setOperator( EOperatorType.Manager.index(),manager.getFullName());
                    operateInfo.setOperateNote("延期租借，原租借时间："+ DateFormatUtils.format(deviceOrder.getStartDate(),"yyyy-MM-dd") +"，原因："+ note);
                    try {
                    if(BXSCNShopOrderService.self(createDate).extensionLeaseDay(deviceOrder,startDate,operateInfo)){
                        result.setCode(DtoConstants.SUCCESS, null);
                    }
                    } catch (LogicException e) {
                        result.setMsg(e.getMessage());
                    }
                }else {
                    result.setMsg("未找到订单信息");
                    return result;
                }
            }catch (ParseException e) {
                log.error(e.getMessage(),e);
                result.setMsg("延期时间解析失败");
                return result;
            }
        }
        return result;
    }

    @Route(value = { "/bxscn/shop_order/operate/cancel.html" })
    public String cancel(HttpServletRequest request) {
        return "/bxscn/shop_order/cancel.html";
    }

    @Route(value = { "/bxscn/shop_order/operate/cancel.do" })
    public AjaxResult doCancel(HttpServletRequest request) {
        AjaxResult result = new AjaxResult(DtoConstants.EXECUTE_ERROR, "撤销失败");
        String tradeNo = WebUtils.getString(request, "tradeNo");
        String note = WebUtils.getString(request, "note");
        if (StringTools.isNotBlank(tradeNo)) {
            if (StringTools.isBlank(note)) {
                result.setMsg("请填撤销的原因");
                return result;
            }

            Date createDate = WebUtils.getDate(request,"createDate");
            if(createDate == null){
                createDate = new Date();
            }

            //检查分成
            BusinessOrder businessOrder = BusinessOrderService.self(createDate).getByTradeNo(tradeNo);
            if (businessOrder != null && (BusinessOrderEnum.DivideState.Finish.index().equals(businessOrder.getDivideState())
                    || BusinessOrderEnum.DivideState.CancelExecuting.index().equals(businessOrder.getDivideState()))) {
                result.setMsg("订单已分成，请回滚分成后操作");
                return result;
            }
            try {
                BXSCNShopOrder deviceOrder = BXSCNShopOrderService.self(createDate).getByTradeNo(tradeNo);
                if(deviceOrder == null){
                    result.setMsg("未找到租借订单");
                    return result;
                }

                Manager manager = WebUtils.getAttribute(request, SysConstants.LOGIN_MANAGER, Manager.class);
                OperateInfo operateInfo = new OperateInfo(WebConstants.PROGRAM_TYPE, WebConstants.PROGRAM_TYPE_NAME);
                operateInfo.setOperator(EOperatorType.Manager.index(), manager.getFullName());
                operateInfo.setOperateNote(note);

                Date cancelDate = new Date();

                int cancelResult = BXSCNShopOrderService.self(deviceOrder.getCreateDate()).cancel(deviceOrder, PayServiceFactory.self(), operateInfo);
                if (cancelResult > 0) {
                    //清理缓存，避免定时器重复处理
                    RedisCacheManager.removeWorkingCDCZDeviceOrder(deviceOrder.getTradeNo());
                    if (cancelResult == 2) {
                        deviceOrder = BXSCNShopOrderService.self(deviceOrder.getCreateDate()).getByTradeNo(tradeNo);
                        //同步会员订单
                        MemberBusinessOrderService.self(deviceOrder.getCreateDate()).cancel(deviceOrder.getTradeNo(),
                                deviceOrder.getMoney(),deviceOrder.getPayMoney(),deviceOrder.getWalletMoney());
                        BusinessOrderService.self(deviceOrder.getCreateDate()).cancel(deviceOrder.getTradeNo(), cancelDate);
                    }
                    result.setCode(DtoConstants.SUCCESS, null);
                }
            } catch (LogicException e) {
                result.setMsg(e.getMessage());
            }
        }
        return result;
    }

    @Route("/bxscn/shop_order/operate/refund.html")
    public String refund(HttpServletRequest request) {
        String tradeNo = WebUtils.getString(request,"tradeNo");
        BXSCNShopOrder deviceOrder = BXSCNShopOrderService.self(new Date()).getByTradeNo(tradeNo);
        if(deviceOrder != null) {
            request.setAttribute("refundMoneyStr",deviceOrder.getPayMoneyStr());
        }
        return "/bxscn/shop_order/refund.html";
    }

    @Route(value = {"/bxscn/shop_order/operate/refund.do"})
    public AjaxResult doRefund(HttpServletRequest request, HttpSession session) {
        AjaxResult result = new AjaxResult(DtoConstants.EXECUTE_ERROR, "撤销订单失败");
        String tradeNo = WebUtils.getString(request, "tradeNo");
        Double refundMoneyStr = WebUtils.getDouble(request,"refundMoneyStr");
        String refundNote = WebUtils.getString(request,"refundNote");
        if (StringTools.isNotBlank(tradeNo)) {
            if (refundMoneyStr == null) {
                result.setMsg("请填写退款金额");
                return result;
            }
            if (StringTools.isBlank(refundNote)) {
                result.setMsg("请填写退款原因");
                return result;
            }

            Date createDate = WebUtils.getDate(request,"createDate");
            if(createDate == null){
                createDate = new Date();
            }

            //检查分成
            BusinessOrder businessOrder = BusinessOrderService.self(createDate).getByTradeNo(tradeNo);
            if(businessOrder != null && (BusinessOrderEnum.DivideState.Finish.index().equals(businessOrder.getDivideState())
                    || BusinessOrderEnum.DivideState.CancelExecuting.index().equals(businessOrder.getDivideState()))){
                result.setMsg("订单已分成，请回滚分成后操作");
                return result;
            }

            try {
                BXSCNShopOrder deviceOrder = BXSCNShopOrderService.self(createDate).getByTradeNo(tradeNo);
                if(deviceOrder == null){
                    result.setMsg("未找到租借订单");
                    return result;
                }

                Manager manager = WebUtils.getAttribute(session, SysConstants.SESSION_LOGIN_MANAGER, Manager.class);
                OperateInfo operateInfo = new OperateInfo(WebConstants.PROGRAM_TYPE,WebConstants.PROGRAM_TYPE_NAME);
                operateInfo.setOperator( EOperatorType.Manager.index(),manager.getFullName());
                operateInfo.setOperateNote(refundNote);

                Integer refundMoney = NumberTools.changeMoney(refundMoneyStr);

                int refundResult = BXSCNShopOrderService.self(deviceOrder.getCreateDate()).refund(deviceOrder, refundMoney, PayServiceFactory.self(), operateInfo);
                if (refundResult > 0) {
                    result.setCode(DtoConstants.SUCCESS, null);
                }
            } catch (LogicException e) {
                result.setMsg(e.getMessage());
            }
        }
        return result;
    }

    @Route("/bxscn/shop_order/operate/finish.html")
    public String finish(HttpServletRequest request) {
        String tradeNo = WebUtils.getString(request,"tradeNo");
        Date createDate = WebUtils.getDate(request,"createDate");
        if(createDate == null){
            createDate = new Date();
        }
        BXSCNShopOrder deviceOrder = BXSCNShopOrderService.self(createDate).getByTradeNo(tradeNo);
        if(deviceOrder != null) {
            request.setAttribute("payMoneyStr",deviceOrder.getPayMoneyStr());
        }
        return "/bxscn/shop_order/finish.html";
    }

    @Route(value = { "/bxscn/shop_order/operate/finish.do" })
    public AjaxResult doFinish(HttpServletRequest request) {
        AjaxResult result = new AjaxResult(DtoConstants.EXECUTE_ERROR, "完成失败");
        String tradeNo = WebUtils.getString(request, "tradeNo");
        Date createDate = WebUtils.getDate(request,"createDate");
        Double payMoney = WebUtils.getDouble(request,"payMoneyStr");
        if (StringTools.isNotBlank(tradeNo)) {
            if (payMoney == null) {
                result.setMsg("请填写支付金额");
                return result;
            }

            if(createDate == null){
                createDate = new Date();
            }

            BXSCNShopOrder deviceOrder = BXSCNShopOrderService.self(createDate).getByTradeNo(tradeNo);
            if(deviceOrder == null){
                result.setMsg("未找到租借订单");
                return result;
            }

            Manager manager = WebUtils.getAttribute(request, SysConstants.LOGIN_MANAGER, Manager.class);
            OperateInfo operateInfo = new OperateInfo(WebConstants.PROGRAM_TYPE,WebConstants.PROGRAM_TYPE_NAME);
            operateInfo.setOperator( EOperatorType.Manager.index(),manager.getFullName());
            operateInfo.setOperateNote("后台客服操作完成订单");

            try {
                int finishResult = BXSCNShopOrderService.self(deviceOrder.getCreateDate()).finish(deviceOrder, NumberTools.changeMoney(payMoney), PayServiceFactory.self(), operateInfo);
                if (finishResult > 0) {
                    //清理缓存，避免定时器重复处理
                    RedisCacheManager.removeWorkingBXSCNDeviceOrder(deviceOrder.getTradeNo());
                    if (finishResult == 2) {
                        deviceOrder = BXSCNShopOrderService.self(deviceOrder.getCreateDate()).getByTradeNo(deviceOrder.getTradeNo());
                        //同步会员订单
                        MemberBusinessOrderService.self(deviceOrder.getCreateDate()).finish(deviceOrder.getTradeNo(),deviceOrder.getMoney(), deviceOrder.getPayMoney(),
                                deviceOrder.getWalletMoney(),operateInfo);

                        //触发订单完成
                        JFKafkaProducer producer = KafkaProducerFactory.self().getProducer();
                        if (producer != null) {
                            OperateInfo temp = ClassTools.copy(new OperateInfo(), operateInfo);
                            OrderFinishEvent event = new OrderFinishEvent(EBusinessType.BXSCN_SHOP.index(), deviceOrder.getTradeNo(), deviceOrder.getCreateDate(), temp);
                            KafkaMessage kafkaMessage = new KafkaMessage(KafkaEventConstants.TOPIC_Order, KafkaEventConstants.KEY_OrderFinish, JsonTools.toJson(event));
                            producer.send(kafkaMessage);
                        }else{
                            log.error("未初始化消息队列，订单{{0}}未触发完成事件",deviceOrder.getTradeNo());
                        }
                    }
                    result.setCode(DtoConstants.SUCCESS, null);
                }

            } catch (LogicException e) {
                result.setMsg(e.getMessage());
            }
        }
        return result;
    }

    @Route(value = { "/bxscn/shop_order/operate/external/syn.do" })
    public AjaxResult doExternalSyn(HttpServletRequest request) {
        AjaxResult result = new AjaxResult(DtoConstants.EXECUTE_ERROR, "同步失败");
        String tradeNo = WebUtils.getString(request, "tradeNo");
        Date createDate = WebUtils.getDate(request,"createDate");
        if(createDate == null){
            createDate = new Date();
        }
        BXSCNShopOrder deviceOrder = BXSCNShopOrderService.self(createDate).getByTradeNo(tradeNo);
        if(deviceOrder != null) {
            Manager manager = WebUtils.getAttribute(request, SysConstants.LOGIN_MANAGER, Manager.class);
            OperateInfo operateInfo = new OperateInfo(WebConstants.PROGRAM_TYPE,WebConstants.PROGRAM_TYPE_NAME);
            operateInfo.setOperator( EOperatorType.Manager.index(),manager.getFullName());
            operateInfo.setOperateNote("后台客服操作同步第三方订单");
            try {
                int synResult = BXSCNShopOrderService.self(createDate).synExternal(deviceOrder,PayServiceFactory.self(),operateInfo);
                //同步会员订单
                if (synResult == 1) {
                    MemberBusinessOrderService.self(deviceOrder.getCreateDate()).cancel(deviceOrder.getTradeNo(),deviceOrder.getMoney()
                            ,deviceOrder.getPayMoney(), deviceOrder.getWalletMoney());
                    result.setCode(DtoConstants.SUCCESS,null);
                }else if (synResult == 3) {
                    MemberBusinessOrderService.self(deviceOrder.getCreateDate()).finish(deviceOrder.getTradeNo(),deviceOrder.getMoney()
                            ,deviceOrder.getPayMoney(), deviceOrder.getWalletMoney(),operateInfo);
                    result.setCode(DtoConstants.SUCCESS,null);
                }
            } catch (LogicException e) {
                result.setMsg(e.getMessage());
            }
        }else {
            result.setMsg("未找到订单信息");
        }
        return result;
    }
}
